package com.winit.config.common.components.freemaker;


import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;

/**
 * Freemaker模板工厂
 */
@Component("templateFactory")
public class FreemakerTemplateFactory implements TemplateFactory {
    private static Logger logger = LoggerFactory.getLogger(FreemakerTemplateFactory.class);
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;
    private Configuration configuration;

    @PostConstruct
    public void init() {
        configuration = freeMarkerConfigurer.getConfiguration();
    }


    public String render(String templateContent, Map dataModel) {
        try {
            String templateName = buildTemplateName(templateContent);
            Template template = getTemplate(templateName);
            if (null == template) {
                initTemplate(templateName, templateContent);
            }
            template = getTemplate(templateName);
            StringWriter writer = new StringWriter();
            template.process(dataModel, writer);
            return writer.toString();
        } catch (Exception e) {
            logger.error("模板渲染出错.", e);
            throw new TemplateRenderException(e);
        }
    }

    private Template getTemplate(String templateName) {
        try {
            return configuration.getTemplate(templateName);
        } catch (IOException e) {
            return null;
        }
    }

    private void initTemplate(String templateName, String templateContent) {
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        stringLoader.putTemplate(templateName, templateContent);
        configuration.setTemplateLoader(stringLoader);
    }

    private String buildTemplateName(String templateContent) {
        return String.valueOf(templateContent.hashCode());
    }
}